	// verilator_coverage annotation
	// author       : adam_wu
	// course       : Microprocessor Architecture and Design
	// ID           : 21033075
	// project_name : AdamRiscv(Five-stage Pipelined Processor Based on RV32I)
	
	module adam_riscv(
 020001	    input wire clk,
%000001	    input wire rst
	);
	
 006569	wire          br_ctrl;
 020105	wire[31:0]    br_addr;
%000009	wire          stall;
 013254	wire[31:0]    if_pc;
 164656	wire[31:0]    if_inst;
 006569	wire          flush;
 118690	wire[31:0]    id_inst;
 026385	wire[31:0]    id_pc;
	
 000024	wire          w_regs_en;
 000081	wire[4:0]     w_regs_addr;
 000486	wire[31:0]    w_regs_data;
 112344	wire[31:0]    id_regs_data1;
 131974	wire[31:0]    id_regs_data2;
 000367	wire[31:0]    id_imm;
 000040	wire[2:0]     id_func3_code; 
 006574	wire          id_func7_code;
 019783	wire[4:0]     id_rd;
 006584	wire          id_br;
 000012	wire          id_mem_read;
 000013	wire          id_mem2reg;
 013198	wire[2:0]     id_alu_op;
%000002	wire          id_mem_write;
 000036	wire[1:0]     id_alu_src1;
 000032	wire[1:0]     id_alu_src2;
%000009	wire          id_br_addr_mode;
 000022	wire          id_regs_write;
 026347	wire[4:0]     id_rs1;
 013233	wire[4:0]     id_rs2;
 000078	wire[4:0]     ex_rs1;
 000096	wire[4:0]     ex_rs2;
 019817	wire[31:0]    ex_pc;
 000707	wire[31:0]    ex_regs_data1;
 000629	wire[31:0]    ex_regs_data2;
 000392	wire[31:0]    ex_imm;
 000041	wire[2:0]     ex_func3_code; 
%000007	wire          ex_func7_code;
 000083	wire[4:0]     ex_rd;
 006584	wire          ex_br;
 000013	wire          ex_mem_read;
 000013	wire          ex_mem2reg;
 019767	wire[2:0]     ex_alu_op;
%000002	wire          ex_mem_write;
 000036	wire[1:0]     ex_alu_src1;
 000034	wire[1:0]     ex_alu_src2;
 006579	wire          ex_br_addr_mode;
 000024	wire          ex_regs_write;
 000639	wire[31:0]    ex_alu_o;
	
 000031	wire[1:0]     forwardA;
 000027	wire[1:0]     forwardB;
	
 000097	wire [4:0]    me_rs2;
 000631	wire [31:0]   me_regs_data2;
 000658	wire [31:0]   me_alu_o;
 000083	wire [4:0]    me_rd;
 000012	wire          me_mem_read;
 000013	wire          me_mem2reg;
%000003	wire          me_mem_write;
 000023	wire          me_regs_write;
 000259	wire[31:0]    me_mem_data;
 000040	wire[2:0]     me_func3_code;  
	
%000001	wire          forward_data;
	
 000272	wire[31:0]    wb_mem_data;
 000659	wire[31:0]    wb_alu_o;
 000013	wire          wb_mem2reg;
	
	stage_if u_stage_if(
	    .clk      (clk      ),
	    .rst      (rst      ),
	    .pc_stall (stall    ),
	    .br_addr  (br_addr  ),
	    .br_ctrl  (br_ctrl  ),
	    .if_inst  (if_inst  ),
	    .if_pc    (if_pc    )
	);
	
	
	reg_if_id u_reg_if_id(
	    .clk         (clk         ),
	    .rst         (rst         ),
	    .if_pc       (if_pc       ),
	    .if_inst     (if_inst     ),
	    .id_inst     (id_inst     ),
	    .id_pc       (id_pc       ),
	    .if_id_flush (flush       ),
	    .if_id_stall (stall       )
	);
	
 000276	wire[31:0] id_m_data;
%000003	wire w_m_en;
%000003	wire id_m_write;
 006604	wire [1:0] id_m_w_index;
 006611	wire [1:0] id_m_r_index;
 000037	wire [1:0] w_m_index;
 026364	wire [6:0] id_inst_opcode;
%000230	wire[31:0] id_r_matrix_mopa [3:0];
%000003	wire id_matrix_mopa_en;
%000003	wire w_matrix_mopa_en;
%000420	wire [31:0] w_matrix_mopa[3:0];
	stage_id u_stage_id(
	    .clk             (clk             ),
	    .rst             (rst             ),
	    .id_inst         (id_inst         ),
	    .w_regs_en       (w_regs_en       ),
	    .w_regs_addr     (w_regs_addr     ),
	    .w_regs_data     (w_regs_data     ),
	    .ctrl_stall      (stall           ),
	    .id_regs_data1   (id_regs_data1   ),
	    .id_regs_data2   (id_regs_data2   ),
	    .id_imm          (id_imm          ),
	    .id_func3_code   (id_func3_code   ),
	    .id_func7_code   (id_func7_code   ),
	    .id_rd           (id_rd           ),
	    .id_br           (id_br           ),
	    .id_mem_read     (id_mem_read     ),
	    .id_mem2reg      (id_mem2reg      ),
	    .id_alu_op       (id_alu_op       ),
	    .id_mem_write    (id_mem_write    ),
	    .id_alu_src1     (id_alu_src1     ),
	    .id_alu_src2     (id_alu_src2     ),
	    .id_br_addr_mode (id_br_addr_mode ),
	    .id_regs_write   (id_regs_write   ),
	    .id_rs1          (id_rs1          ),
	    .id_rs2          (id_rs2          ),
	    .w_m_en          (w_m_en),
	    .id_m_data       (id_m_data),
	    .id_m_write      (id_m_write),
	    .id_m_w_index    (id_m_w_index),
	    .w_m_index       (w_m_index),
	    .id_m_r_index    (id_m_r_index),
	    .id_inst_opcode  (id_inst_opcode),
	    .id_r_matrix_mopa(id_r_matrix_mopa),
	    .id_matrix_mopa_en(id_matrix_mopa_en),
	    .w_matrix_mopa   (w_matrix_mopa),
	    .w_matrix_mopa_en(w_matrix_mopa_en),
	    .me_matrix_mopa_en(me_matrix_mopa_en),
	    .me_matrix_mopa_o(me_matrix_mopa_o)
	);
	
	
 000291	wire [31:0] ex_m_data;
%000002	wire ex_m_write;
 000038	wire [1:0] ex_m_w_index;
 000044	wire [1:0] ex_m_r_index;
 026368	wire [6:0] ex_inst_opcode;
 506047	wire [31:0] ex_r_matrix_mopa [3:0];
%000002	wire ex_matrix_mopa_en;
	reg_id_ex u_reg_id_ex(
	    .clk             (clk             ),
	    .rst             (rst             ),
	    .id_pc           (id_pc           ),
	    .id_regs_data1   (id_regs_data1   ),
	    .id_regs_data2   (id_regs_data2   ),
	    .id_imm          (id_imm          ),
	    .id_func3_code   (id_func3_code   ),
	    .id_func7_code   (id_func7_code   ),
	    .id_rd           (id_rd           ),
	    .id_br           (id_br           ),
	    .id_mem_read     (id_mem_read     ),
	    .id_mem2reg      (id_mem2reg      ),
	    .id_alu_op       (id_alu_op       ),
	    .id_mem_write    (id_mem_write    ),
	    .id_alu_src1     (id_alu_src1     ),
	    .id_alu_src2     (id_alu_src2     ),
	    .id_br_addr_mode (id_br_addr_mode ),
	    .id_regs_write   (id_regs_write   ),
	    .id_ex_flush     (flush           ),
	    .id_rs1          (id_rs1          ),
	    .id_rs2          (id_rs2          ),
	    .ex_rs1          (ex_rs1          ),
	    .ex_rs2          (ex_rs2          ),
	    .ex_pc           (ex_pc           ),
	    .ex_regs_data1   (ex_regs_data1   ),
	    .ex_regs_data2   (ex_regs_data2   ),
	    .ex_imm          (ex_imm          ),
	    .ex_func3_code   (ex_func3_code   ),
	    .ex_func7_code   (ex_func7_code   ),
	    .ex_rd           (ex_rd           ),
	    .ex_br           (ex_br           ),
	    .ex_mem_read     (ex_mem_read     ),
	    .ex_mem2reg      (ex_mem2reg      ),
	    .ex_alu_op       (ex_alu_op       ),
	    .ex_mem_write    (ex_mem_write    ),
	    .ex_alu_src1     (ex_alu_src1     ),
	    .ex_alu_src2     (ex_alu_src2     ),
	    .ex_br_addr_mode (ex_br_addr_mode ),
	    .ex_regs_write   (ex_regs_write   ),
	    .id_m_data       (id_m_data),
	    .ex_m_data       (ex_m_data),
	    .id_m_write      (id_m_write),
	    .ex_m_write      (ex_m_write),
	    .id_m_w_index      (id_m_w_index),
	    .ex_m_w_index      (ex_m_w_index),
	    .id_m_r_index      (id_m_r_index),
	    .ex_m_r_index      (ex_m_r_index),
	    .id_inst_opcode  (id_inst_opcode),
	    .ex_inst_opcode  (ex_inst_opcode),
	    .id_r_matrix_mopa(id_r_matrix_mopa),
	    .ex_r_matrix_mopa(ex_r_matrix_mopa),
	    .id_matrix_mopa_en(id_matrix_mopa_en),
	    .ex_matrix_mopa_en(ex_matrix_mopa_en)
	);
	
	
%000283	wire[31:0] matrix_mopa_o[3:0];
	stage_ex u_stage_ex(
	    .ex_pc           (ex_pc           ),
	    .ex_regs_data1   (ex_regs_data1   ),
	    .ex_regs_data2   (ex_regs_data2   ),
	    .ex_imm          (ex_imm          ),
	    .ex_func3_code   (ex_func3_code   ),
	    .ex_func7_code   (ex_func7_code   ),
	    .ex_alu_op       (ex_alu_op       ),
	    .ex_alu_src1     (ex_alu_src1     ),
	    .ex_alu_src2     (ex_alu_src2     ),
	    .ex_br_addr_mode (ex_br_addr_mode ),
	    .ex_br           (ex_br           ),
	    .forwardA        (forwardA        ),
	    .forwardB        (forwardB        ),
	    .me_alu_o        (me_alu_o        ),
	    .w_regs_data     (w_regs_data     ),
	    .ex_alu_o        (ex_alu_o        ),
	    .br_pc           (br_addr         ),
	    .br_ctrl         (br_ctrl         ),
	    .ex_m_data       (ex_m_data),
	    .ex_r_matrix_mopa(ex_r_matrix_mopa),
	    .matrix_mopa_o(matrix_mopa_o)
	);
	
%000002	wire me_m_write;
 000038	wire [1:0] me_m_w_index;
 026361	wire [6:0] me_inst_opcode;
 000288	wire [31:0] me_m_data; //st.tile M[?]
%000413	wire [31:0] me_matrix_mopa_o[3:0];
%000003	wire me_matrix_mopa_en;
	reg_ex_mem u_reg_ex_mem(
	    .clk           (clk           ),
	    .rst           (rst           ),
	    .ex_regs_data2 (ex_regs_data2 ),
	    .ex_alu_o      (ex_alu_o      ),
	    .ex_rd         (ex_rd         ),
	    .ex_mem_read   (ex_mem_read   ),
	    .ex_mem2reg    (ex_mem2reg    ),
	    .ex_mem_write  (ex_mem_write  ),
	    .ex_regs_write (ex_regs_write ),
	    .ex_func3_code (ex_func3_code ),
	    .ex_rs2        (ex_rs2        ),
	    .me_rs2        (me_rs2        ),
	    .me_regs_data2 (me_regs_data2 ),
	    .me_alu_o      (me_alu_o      ),
	    .me_rd         (me_rd         ),
	    .me_mem_read   (me_mem_read   ),
	    .me_mem2reg    (me_mem2reg    ),
	    .me_mem_write  (me_mem_write  ),
	    .me_regs_write (me_regs_write ),
	    .me_func3_code (me_func3_code ),
	    .ex_m_write    (ex_m_write),
	    .me_m_write    (me_m_write),
	    .ex_m_w_index    (ex_m_w_index),
	    .me_m_w_index    (me_m_w_index),
	    .ex_m_data     (ex_m_data),
	    .me_m_data     (me_m_data),
	    .ex_inst_opcode(ex_inst_opcode),
	    .me_inst_opcode(me_inst_opcode),
	    .matrix_mopa_o(matrix_mopa_o),
	    .me_matrix_mopa_o(me_matrix_mopa_o),
	    .ex_matrix_mopa_en(ex_matrix_mopa_en),
	    .me_matrix_mopa_en(me_matrix_mopa_en)
	);
	
	
	stage_mem u_stage_mem(
	    .clk           (clk           ),
	    .rst           (rst           ),
	    .me_regs_data2 (me_regs_data2 ),
	    .me_alu_o      (me_alu_o      ),
	    .me_mem_read   (me_mem_read   ),
	    .me_mem_write  (me_mem_write  ),
	    .me_func3_code (me_func3_code ),
	    .forward_data  (forward_data  ),
	    .w_regs_data   (w_regs_data   ),
	    .me_mem_data   (me_mem_data   ),
	    .me_m_write    (me_m_write),
	    .me_inst_opcode(me_inst_opcode),
	    .me_m_data     (me_m_data)
	);
	
%000418	wire [31:0] wb_matrix_mopa_o[3:0];
	reg_mem_wb u_reg_mem_wb(
	    .clk           (clk           ),
	    .rst           (rst           ),
	    .me_mem_data   (me_mem_data   ),
	    .me_alu_o      (me_alu_o      ),
	    .me_rd         (me_rd         ),
	    .me_mem2reg    (me_mem2reg    ),
	    .me_regs_write (me_regs_write ),
	    .wb_mem_data   (wb_mem_data   ),
	    .wb_alu_o      (wb_alu_o      ),
	    .wb_rd         (w_regs_addr   ),
	    .wb_mem2reg    (wb_mem2reg    ),
	    .wb_regs_write (w_regs_en     ),
	    .me_m_write    (me_m_write),
	    .wb_m_write    (w_m_en),
	    .me_m_w_index    (me_m_w_index),
	    .wb_m_w_index    (w_m_index),
	    .me_matrix_mopa_o(me_matrix_mopa_o),
	    .wb_matrix_mopa_o(wb_matrix_mopa_o),
	    .me_matrix_mopa_en(me_matrix_mopa_en),
	    .wb_matrix_mopa_en(w_matrix_mopa_en)
	);
	
	
	stage_wb u_stage_wb(
	    .wb_mem_data (wb_mem_data ),
	    .wb_alu_o    (wb_alu_o    ),
	    .wb_mem2reg  (wb_mem2reg  ),
	    .w_regs_data (w_regs_data ),
	    .wb_matrix_mopa_o(wb_matrix_mopa_o),
	    .w_matrix_mopa(w_matrix_mopa)
	);
	
	forwarding u_forwarding(
	    .ex_rs1        (ex_rs1        ),
	    .ex_rs2        (ex_rs2        ),
	    .me_rd         (me_rd         ),
	    .wb_rd         (w_regs_addr   ),
	    .me_rs2        (me_rs2        ),
	    .me_mem_write  (me_mem_write  ),
	    .me_regs_write (me_regs_write ),
	    .wb_regs_write (w_regs_en     ),
	    .forwardA      (forwardA      ),
	    .forwardB      (forwardB      ),
	    .forward_data  (forward_data  ),
	    .wb_m_index    (w_m_index),
	    .ex_m_r_index    (ex_m_r_index),
	    .wb_m_write    (w_m_en)
	);
	
	hazard_detection u_hazard_detection(
	    .ex_mem_read (ex_mem_read ),
	    .id_rs1      (id_rs1      ),
	    .id_rs2      (id_rs2      ),
	    .ex_rd       (ex_rd       ),
	    .br_ctrl     (br_ctrl     ),
	    .load_stall  (stall       ),
	    .flush       (flush       )
	);
	
	
	endmodule
	
